package com.geovis.emergency.spd.biz.zwdd.service.impl;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.xxpt.gateway.shared.api.request.*;
import com.alibaba.xxpt.gateway.shared.api.response.*;
import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentPostClient;
import com.alibaba.xxpt.gateway.shared.client.http.api.OapiSpResultContent;
import com.geovis.common.core.exception.BizException;
import com.geovis.emergency.spd.biz.zwdd.handler.EventEnum;
import com.geovis.emergency.spd.biz.zwdd.handler.ZwddEventCallbackHandler;
import com.geovis.emergency.spd.biz.zwdd.handler.ZwddSynchronizeHandler;
import com.geovis.emergency.spd.biz.zwdd.props.ZwddProperties;
import com.geovis.emergency.spd.biz.zwdd.service.IZwddServcie;
import com.geovis.emergency.spd.entity.zwdd.pojo.EmployeeAccount;
import com.geovis.emergency.spd.entity.zwdd.pojo.OapiGettokenJsonResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 海证钉服务接口实现类
 * </p>
 *
 * @author 王响
 * @since 2022-03-15
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ZwddServcieImpl implements IZwddServcie {

    private final ExecutableClient executableClient;

    private final ZwddProperties zwddProperties;

    private final ZwddEventCallbackHandler zwddEventCallbackHandler;

    @Async
    @Override
    public void synchronize(Boolean removeOldDeptAndUser, Boolean removeOldUser) {
        ZwddSynchronizeHandler zwddSynHandler = new ZwddSynchronizeHandler(executableClient, zwddProperties);
        boolean rodau = null != removeOldDeptAndUser && removeOldDeptAndUser;
        boolean rou = null != removeOldUser && removeOldUser;
        zwddSynHandler.synchronize(rodau, rou);
    }

    @Override
    public void registerListenerEvent() {
        log.debug(" ===============> 开始海证通注册事件  <=============== ");
        EventEnum[] values = EventEnum.values();
        OapiOpenplatformMessageRegisterEventCallbackRequest request;
        for (EventEnum eventEnum : values) {
            if (Boolean.TRUE.equals(eventEnum.enable)) {
                request = new OapiOpenplatformMessageRegisterEventCallbackRequest();
                IntelligentGetClient intelligentGetClient = executableClient.newIntelligentGetClient(request.getApiUrl());
                request.setEventTag(eventEnum.code);
                request.setCallbackUrl(zwddProperties.getEventCallbackUrl());
                OapiOpenplatformMessageRegisterEventCallbackResponse apiResult = intelligentGetClient.get(request);
                log.debug(JSONUtil.toJsonStr(apiResult));
            }
        }
    }

    @Override
    public synchronized void eventCallBack(String eventTag, String content) {

        log.debug(StrUtil.format(StrUtil.format("=====================进入【{}】方法回调=====================", eventTag)));

        if (ObjectUtil.isEmpty(eventTag) || ObjectUtil.isEmpty(content)) {
            return;
        }

        EventEnum eventEnum = EventEnum.format(eventTag);
        if (null == eventEnum || StrUtil.isEmpty(eventEnum.callbackMethod)) {
            return;
        }
        log.debug(StrUtil.format("=====================开始执行【{}】回调方法=====================", eventEnum.name));
        log.debug(content);
        // 反射执行对应的方法
        ReflectUtil.invoke(zwddEventCallbackHandler, eventEnum.callbackMethod, content);
        log.debug(StrUtil.format("=====================结束执行【{}】回调方法=====================", eventEnum.name));
    }

    @Override
    public EmployeeAccount authLogin(String authCode) {
        OapiGettokenJsonResult tokenResult = getOapiGettokenJsonResult();
        OapiRpcOauth2DingtalkAppUserJsonRequest request = new OapiRpcOauth2DingtalkAppUserJsonRequest();
        IntelligentPostClient intelligentPostClient = executableClient.newIntelligentPostClient(request.getApiUrl());
        OapiRpcOauth2DingtalkAppTokenJsonRequest oapiRpcOauth2DingtalkAppTokenJsonRequest = new OapiRpcOauth2DingtalkAppTokenJsonRequest();
        //登录access_token
        oapiRpcOauth2DingtalkAppTokenJsonRequest.setAccess_token(tokenResult.getAccessToken());
        //临时授权码
        oapiRpcOauth2DingtalkAppTokenJsonRequest.setAuth_code(authCode);
        //获取结果
        OapiRpcOauth2DingtalkAppTokenJsonResponse apiResult = intelligentPostClient.post(oapiRpcOauth2DingtalkAppTokenJsonRequest);
        if (ObjectUtil.isEmpty(apiResult) || ObjectUtil.isEmpty(apiResult.getContent())) {
            throw new BizException("认证失败");
        }
        log.debug(JSONUtil.toJsonStr(apiResult.getContent()));
        JSONObject jsonObject = JSONUtil.toBean(apiResult.getContent(), JSONObject.class);
        if (Boolean.FALSE.equals(jsonObject.getBool("success"))) {
            throw new BizException(jsonObject.getStr("responseMessage"));
        }
        return jsonObject.getByPath("content.data", EmployeeAccount.class);
    }

    @Override
    public JSONObject getTicket() {
        OapiGettokenJsonResult tokenResult = getOapiGettokenJsonResult();

        OapiGetJsapiTokenJsonRequest oapiGetJsapiTokenJsonRequest = new OapiGetJsapiTokenJsonRequest();
        oapiGetJsapiTokenJsonRequest.setAccessToken(tokenResult.getAccessToken());
        IntelligentGetClient intelligentGetClient = executableClient.newIntelligentGetClient(oapiGetJsapiTokenJsonRequest.getApiUrl());
        OapiGetJsapiTokenJsonResponse apiResult = intelligentGetClient.get(oapiGetJsapiTokenJsonRequest);

        if (!apiResult.getSuccess()) {
            throw new BizException("获取票据失败；请检查网络情况");
        }
        OapiSpResultContent oapiSpResultContent = apiResult.getContent();
        if (!oapiSpResultContent.getSuccess()) {
            throw new BizException("获取票据失败；请检查网络情况");
        }


        return JSONUtil.parseObj(oapiSpResultContent.getData());
    }

    @Override
    public void removeEvent(Long eventCallbackId) {
        OapiOpenplatformMessageDeleteEventCallbackDefineRequest request = new OapiOpenplatformMessageDeleteEventCallbackDefineRequest();
        IntelligentGetClient intelligentGetClient = executableClient.newIntelligentGetClient(request.getApiUrl());
        OapiOpenplatformMessageDeleteEventCallbackDefineRequest oapiOpenplatformMessageDeleteEventCallbackDefineRequest = new OapiOpenplatformMessageDeleteEventCallbackDefineRequest();
        oapiOpenplatformMessageDeleteEventCallbackDefineRequest.setEventCallbackId(eventCallbackId);
        intelligentGetClient.get(oapiOpenplatformMessageDeleteEventCallbackDefineRequest);
    }

    @Override
    public JSONArray getEventList() {
        OapiOpenplatformMessageQueryCallbackDefineRequest request = new OapiOpenplatformMessageQueryCallbackDefineRequest();
        IntelligentGetClient intelligentGetClient = executableClient.newIntelligentGetClient(request.getApiUrl());
        OapiOpenplatformMessageQueryCallbackDefineRequest oapiOpenplatformMessageQueryCallbackDefineRequest = new OapiOpenplatformMessageQueryCallbackDefineRequest();
        OapiOpenplatformMessageQueryCallbackDefineResponse apiResult = intelligentGetClient.get(oapiOpenplatformMessageQueryCallbackDefineRequest);
        if (ObjectUtil.isEmpty(apiResult) || ObjectUtil.isEmpty(apiResult.getContent())) {
            return new JSONArray();
        }
        String content = apiResult.getContent();
        log.debug(content);
        JSONArray jsonArray = JSONUtil.parseArray(content);
        jsonArray.forEach(json -> {
            JSONObject object = (JSONObject) json;
            EventEnum eventEnum = EventEnum.format(object.getStr("eventTag"));
            if (null != eventEnum) {
                object.putOpt("eventTagText", eventEnum.name);
            }
        });
        return jsonArray;
    }

    /**
     * 通过秘钥获取accessToken
     */
    private OapiGettokenJsonResult getOapiGettokenJsonResult() {
        OapiGettokenJsonRequest request = new OapiGettokenJsonRequest();
        IntelligentGetClient intelligentGetClient = executableClient.newIntelligentGetClient(request.getApiUrl());
        OapiGettokenJsonRequest oapiGettokenJsonRequest = new OapiGettokenJsonRequest();
        oapiGettokenJsonRequest.setAppkey(zwddProperties.getAppkey());
        oapiGettokenJsonRequest.setAppsecret(zwddProperties.getAppsecret());
        OapiGettokenJsonResponse apiResult = intelligentGetClient.get(oapiGettokenJsonRequest);
        if (ObjectUtil.isEmpty(apiResult) || ObjectUtil.isEmpty(apiResult.getContent())) {
            throw new BizException("获取token失败;请检查网络或AK/SK是否正确！");
        }
        return JSONUtil.toBean(apiResult.getContent().getData(), OapiGettokenJsonResult.class);
    }

}
